#include <Riostream.h>
#include <CpLog.h>

#include "CpMagneticFieldMap.h"

ClassImp(CpMagneticFieldMap);

//______________________________________________________________________________
CpMagneticFieldMap::CpMagneticFieldMap(const char *name, const char *title, TString rootFile)
   : TNamed(name, title),
     fMagneticMapRootFileName(rootFile),
     fOutFile(0),
     fTree(0),
     fMagFieldObj(0)

{
//
// Constructor
//
   CpDebug(CpLog::kDebug + 5, "<-");
   CpDebug(CpLog::kDebug + 5, "->");
}

//______________________________________________________________________________
CpMagneticFieldMap::~CpMagneticFieldMap()
{
//
// Destructor.
//

   CpDebug(CpLog::kDebug + 5, "<-");
   CpDebug(CpLog::kDebug + 5, "->");

}

//______________________________________________________________________________
void CpMagneticFieldMap::Reset()
{
//
// Resets all variables
//
   CpDebug(CpLog::kDebug + 5, "<-");

   if (fOutFile) {
      fOutFile->Close();
      delete fOutFile;
      fOutFile = 0;
   }

   if (fTree) {
      delete fTree;
      fTree = 0;
   }

   if (fMagFieldObj) {
      delete fMagFieldObj;
      fMagFieldObj = 0;
   }

   CpDebug(CpLog::kDebug + 5, "->");
}


Bool_t CpMagneticFieldMap::OpenMagneticMapRootFile(TString fileName)
{


   if (fileName.IsNull()) {
      if (fMagneticMapRootFileName.IsNull()) {
         CpError(Form("String fMagneticMapRootFile is %s !!! Exiting ...", fMagneticMapRootFileName.Data()));
         return kFALSE;
      }
   } else {
      fMagneticMapRootFileName = fileName.Data();
   }

   fOutFile = TFile::Open(fMagneticMapRootFileName.Data());

   if (!fOutFile) {
      CpError(Form("Error opening %s file !!!", fMagneticMapRootFileName.Data()));
      return kFALSE;
   }

   fTree = (TTree *) fOutFile->Get("ColdPigMagent");

   if (!fTree) {
      CpError("Error opening ColdPigMagent tree !!!");
      return kFALSE;
   }

   CpDebug(CpLog::kDebug, Form("File %s was open successfully ...", fMagneticMapRootFileName.Data()));

   return kTRUE;
}


//______________________________________________________________________________
Bool_t CpMagneticFieldMap::ImportFromTxtFile(TString infileName, TString outfileName)
{
//
// Fills tree from the file
//
   CpDebug(CpLog::kDebug + 5, "<-");

   CpInfo(Form("Importing file %s ... ", infileName.Data()));

   Reset();

   fOutFile = TFile::Open(outfileName.Data(), "RECREATE");
   fTree = new TTree("ColdPigMagent", Form("%s", GetName()));
   fMagFieldObj = new CpMagneticFieldMapObject();
//     CpInfo(Form("%p",fMagFieldObj));
   fTree->Branch("field", &fMagFieldObj);

   const Int_t rows = 6;

   // Open the input stream
   ifstream fileIn;
   fileIn.open(infileName.Data());

   if (!fileIn.is_open()) {
      CpError(Form("File %s was not found. Skipping ...", infileName.Data()));
      return kFALSE;
   }

   Int_t count = 0;
   Int_t index;
   Double_t num[rows];

   Int_t i;

   for (i = 0; i < rows; i++)
      num[i] = 0.0;

   // Read the input list of files and add them to the chain
   TString line;

   while (fileIn.good()) {
      fileIn >> line;

      if (line.IsNull()) continue;

      index = count % rows;
      num[index] = line.Atof();

      if (index == rows - 1) {
         CpDebug(CpLog::kDebug + 4, Form("%.2E %.2E %.2E Bx=%.5E By=%.5E Bz=%.5E", num[0], num[1], num[2], num[3], num[4], num[5]));
         fMagFieldObj->SetPosition(num[0], num[1], num[2]);
         fMagFieldObj->SetMagField(num[3], num[4], num[5]);
         fTree->Fill();
         fMagFieldObj->Clear();
      }

      count++;
   }

//     fTree->Write();
   fTree->Write("", TObject::kOverwrite);
   CloseOutputFile();

   fMagneticMapRootFileName = outfileName.Data();
   CpInfo(Form("Importing file %s OK ... ", infileName.Data()));
   CpInfo(Form("File %s was created ... ", outfileName.Data()));
   CpDebug(CpLog::kDebug + 5, "->");
   return kTRUE;
}

Long64_t CpMagneticFieldMap::FillHistogram(TH1 *hist, Int_t indexMag, Int_t indexAxis, Double_t axisOneAfter, Double_t axisTwoAfter)
{

   CpDebug(CpLog::kDebug + 5, "<-");

   if (!OpenMagneticMapRootFile())
      return -1;

   Long64_t entriesAccepted = 0;
   CpMagneticFieldMapObject *obj = 0;
   fTree->SetBranchAddress("field", &obj);

//
   for (Int_t i = 0; i < fTree->GetEntries(); i++) {
      CpDebug(CpLog::kDebug + 4, Form("Reading entry %d", i));
      fTree->GetEntry(i);

      if (!obj) continue;

//     CpDebug(CpLog::kDebug,Form("%d %f %f",indexAxis,obj->GetPos(kY),obj->GetPos(kZ)));
      if ((indexAxis == 0) && (obj->GetPos(1) == axisOneAfter) && (obj->GetPos(2) == axisTwoAfter)) {
         hist->SetBinContent(hist->GetXaxis()->FindBin(obj->GetPos(0)), obj->GetMagField(indexMag));
         entriesAccepted++;
      } else if ((indexAxis == 1) && (obj->GetPos(0) == axisOneAfter) && (obj->GetPos(2) == axisTwoAfter)) {
         hist->SetBinContent(hist->GetXaxis()->FindBin(obj->GetPos(1)), obj->GetMagField(indexMag));
         entriesAccepted++;
      } else if ((indexAxis == 2) && (obj->GetPos(0) == axisOneAfter) && (obj->GetPos(1) == axisTwoAfter)) {
         hist->SetBinContent(hist->GetXaxis()->FindBin(obj->GetPos(2)), obj->GetMagField(indexMag));
         entriesAccepted++;
      }
   }

   CpDebug(CpLog::kDebug + 5, "->");
   return entriesAccepted;
}


Long64_t CpMagneticFieldMap::FillHistogram(TH2 *hist, Int_t indexMag, Int_t indexAxis1, Int_t indexAxis2, Double_t axisAfter)
{
   CpDebug(CpLog::kDebug + 5, "<-");

   if (!OpenMagneticMapRootFile())
      return -1;

   Long64_t entriesAccepted = 0;
   CpMagneticFieldMapObject *obj = 0;
   fTree->SetBranchAddress("field", &obj);

   for (Int_t i = 0; i < fTree->GetEntries(); i++) {
      CpDebug(CpLog::kDebug + 4, Form("Reading entry %d", i));
      fTree->GetEntry(i);

      if (!obj) continue;

//         CpDebug(CpLog::kDebug,Form("%d %f %f",posAxis,obj->GetPos(kY),obj->GetPos(kZ)));
      if (((indexAxis1 == 0) && (indexAxis2 == 1)) || ((indexAxis1 == 1) && (indexAxis2 == 0))) {
         if (obj->GetPos(2) == axisAfter) {
            hist->SetBinContent(hist->GetXaxis()->FindBin(obj->GetPos(0)), hist->GetYaxis()->FindBin(obj->GetPos(1)), obj->GetMagField(indexMag));
            entriesAccepted++;
         }
      } else if (((indexAxis1 == 1) && (indexAxis2 == 2)) || ((indexAxis1 == 2) && (indexAxis2 == 1))) {
         if (obj->GetPos(0) == axisAfter) {
            hist->SetBinContent(hist->GetXaxis()->FindBin(obj->GetPos(1)), hist->GetYaxis()->FindBin(obj->GetPos(2)), obj->GetMagField(indexMag));
            entriesAccepted++;

         }
      } else if (((indexAxis1 == 2) && (indexAxis2 == 0)) || ((indexAxis1 == 0) && (indexAxis2 == 2))) {
         if (obj->GetPos(1) == axisAfter) {
            hist->SetBinContent(hist->GetXaxis()->FindBin(obj->GetPos(0)), hist->GetYaxis()->FindBin(obj->GetPos(2)), obj->GetMagField(indexMag));
//         CpDebug(CpLog::kDebug,Form("%f %f %f",obj->GetPos(0),obj->GetPos(2),obj->GetMagField(indexMag)));
            entriesAccepted++;
         }
      }
   }

   CpDebug(CpLog::kDebug + 5, "->");
   return entriesAccepted;
}


Long64_t CpMagneticFieldMap::FillHistogram(TH3 *hist, Int_t indexMag)
{
   CpDebug(CpLog::kDebug + 5, "<-");

   if (!OpenMagneticMapRootFile())
      return -1;

   Long64_t entriesAccepted = 0;
   CpMagneticFieldMapObject *obj = 0;
   fTree->SetBranchAddress("field", &obj);
   Int_t i;

   for (i = 0; i < fTree->GetEntries(); i++) {
      CpDebug(CpLog::kDebug + 4, Form("Reading entry %d", i));
      fTree->GetEntry(i);

      if (!obj) continue;

      hist->SetBinContent(hist->GetXaxis()->FindBin(obj->GetPos(0)), hist->GetYaxis()->FindBin(obj->GetPos(1)), hist->GetZaxis()->FindBin(obj->GetPos(2)), obj->GetMagField(indexMag));
      entriesAccepted++;
   }

   CpDebug(CpLog::kDebug + 5, "->");
   return entriesAccepted;
}

Bool_t CpMagneticFieldMap::VerifyDataWithFitFunction(TF3 *fun, CpMagneticFieldMap::EAxis fieldAxis, Long64_t times)
{

   CpDebug(CpLog::kDebug + 5, "<-");

   if (!OpenMagneticMapRootFile()) return -1;

   Double_t fitValue;
   CpMagneticFieldMapObject *obj = 0;
   fTree->SetBranchAddress("field", &obj);
   Int_t i;

   for (i = 0; i < fTree->GetEntries(); i++) {
      CpDebug(CpLog::kDebug + 4, Form("Reading entry %d", i));
      fTree->GetEntry(i);

      if (!obj) continue;

      fitValue = fun->Eval(obj->GetPos(kX), obj->GetPos(kY), obj->GetPos(kZ));
      CpInfo(Form("[%.2f,%.2f,%.2f] %f %f", obj->GetPos(kX), obj->GetPos(kY), obj->GetPos(kZ), obj->GetMagField(fieldAxis)*times, fitValue));
   }

   CpDebug(CpLog::kDebug + 5, "->");
   return kTRUE;
}
